
import Tkinter

import exceptions
class RException(exceptions.Exception): pass
class PyRindPropertyException(RException): pass

H='h'
V='v'

#=========utility functions=================================

def stringToUnderlinePosition(s):
	# If given a string '&hello', underline the h. todo: Treat && as a normal &.	
	if '&' in s:
		pos = s.find('&')
		text = s.replace('&','',1)
		return text, pos
	else:
		return s , -1

def underlinePositionToString(s, pos):
	if pos==-1: return s
	return s[0:pos] + '&' + s[pos:] 

_dictColors = {'white':(255,255,255), 'black':(0,0,0), 'red':(255,0,0), 'green':(0,255,0), 'blue':(0,0,255),
	'cyan':(0,255,255), 'yellow':(255,255,0), 'magenta': (255,0,255) }
def colorToString(tpl):
	if tpl in _dictColors: 
		tpl = _dictColors[tpl]
	if len(tpl)==3:
		return "#%02x%02x%02x" % (tpl[0],tpl[1],tpl[2])
	else:
		return None
	
def stringToColor(s):
	return (int(s[1:3],16),int(s[3:5],16),int(s[5:7],16))

#=========properties=================================

class PropertyMapping(): #maps Pyrind property to Tkinter property and vice versa
	def lookupForward(self, s):
		raise 'Not implemented'
	def lookupReverse(self, s):
		raise 'Not implemented'


#more complicated than it needs to be, because we defer making the dictionaries for as long as possible.
class BidirectionalDict(PropertyMapping):
	def __init__(self, propname, functionReturningDict):
		self.propname = propname
		self.functionReturningDict = functionReturningDict
		self.dictForward = None #will build later, because it might not be needed.
		self.dictReverse = None #will build later, because it might not be needed.
		
	def lookupReverse(self, s):
		if self.dictReverse == None: self._makeDictReverse()
		if s not in self.dictReverse:
			raise PyRindPropertyException('Pyrind internal error. Getting property "%s", did not expect that tkinter value could be: %s'%(self.propname, s))
		return self.dictReverse[s]
		
	def lookupForward(self, s):
		if not self.dictForward: self._makeDictForward()
		if s not in self.dictForward:
			raise PyRindPropertyException('Property "%s" accepts only the values:%s'%(self.propname, self.getValidKeys()))
		return self.dictForward[s]
	def _makeDictForward(self):
		self.dictForward = self.functionReturningDict()
		self.dictReverse = None
	def _makeDictReverse(self):
		if not self.dictForward: self._makeDictForward()
		self.dictReverse = {}
		for key,value in self.dictForward.iteritems():
			self.dictReverse[value] = key
			
	def getValidKeys(self):
		if not self.dictForward: self._makeDictForward()
		return '"' + '", "'.join(sorted(self.dictForward.keys())) + '"'
		


		
class ColorConversionClass(PropertyMapping):
	def lookupReverse(self, s):
		return stringToColor(s) 
	def lookupForward(self, o):
		res =  colorToString(o) 
		if res==None:
			raise PyRindPropertyException('Not a valid color. Must be in format "red" or (255,0,0)')
		return res
		


#dicts are in lambdas so that the dict isn't built until it is needed.
mapAlignment = BidirectionalDict('alignment',lambda:{'left':Tkinter.LEFT, 'right':Tkinter.RIGHT, 'center':Tkinter.CENTER})
mapBorderstyle = BidirectionalDict('borderstyle',lambda:{'sunken':Tkinter.SUNKEN, 'raised':Tkinter.RAISED,'groove':Tkinter.GROOVE,'ridge':Tkinter.RIDGE,'flat':Tkinter.FLAT})
mapAnchor = BidirectionalDict('anchor', lambda:{'center':Tkinter.CENTER,'top':Tkinter.N, 'topright':Tkinter.NE,'right':Tkinter.E, 'bottomright':Tkinter.SE, 'bottom':Tkinter.S, 'bottomleft':Tkinter.SW, 'left':Tkinter.W, 'topleft':Tkinter.NW})
mapPosition = BidirectionalDict( 'icon_position', lambda:{'center':Tkinter.CENTER,'bottom':Tkinter.BOTTOM,'left':Tkinter.LEFT,'right':Tkinter.RIGHT,'top':Tkinter.TOP})
mapColor = ColorConversionClass()


	